#ifndef __RECORD_H__
#define __RECORD_H__

#include <pthread.h>

#define RECORD_CONFIG_FILE       "/tmp/record.conf"

/**************************** DataType Declarations *************************/
enum record_codec_format
{
    REC_CODEC_H264,
    REC_CODEC_MJPEG,
    REC_CODEC_AAC,
    REC_CODEC_G711A,
    REC_CODEC_G711U,
    REC_CODEC_PCM_ALAW,
    REC_CODEC_MAX
};
enum rsc_record_mode
{
    REC_MODE_UNDEF = 0,
    REC_MODE_AUTO, /* record when poweroff */
    REC_MODE_TIMER, /* timing record,assign start and end time */
    REC_MODE_EVENT, /* event trigger record,such open-door ,alarm event */
    REC_MODE_CYCLE, /* record plan mode,day,week,month or year plan */
};

enum rsc_stream_type 
{
    RSC_STREAM_VIDEO = 0x01,
    RSC_STREAM_AUDIO = 0x02,
    RSC_STREAM_META  = 0x04,
    RSC_STREAM_MAX
};

typedef struct rsc_mode_attr 
{
    int mode;
    time_t timer_start; 
    time_t timer_end;
    int event_trigger;/* set to 1 when event happen */
    int event_time; /* event record time length,unit second */
    char event_desc[64];/* event description ,such as "alarm" */
}st_rec_mode_param;

/* frame data structure to record */
struct record_frame_info
{
    unsigned char *addr;
    unsigned int size; /* addr availabe size */
    unsigned int len; /* frame length */
    unsigned long pts;
    unsigned int flag;
    int index;/* frame index, -1 is invalid */ 
};

typedef void* RSC_SINK_HANDLE;
struct record_sink 
{
    char 			mpoint[64];//device mount point	
    char 			sname[128];//sink absolute path and name	
    time_t 			ctime; // create time
    unsigned int 		ssize; // sink size ,unit bytes

    RSC_SINK_HANDLE		psink;
    int 			user_len;
    unsigned char 		user_data[1024];
    unsigned char 		audio_buf[1024];
    unsigned char 		*video_buf;
};
struct rsc_stream_confset
{
    char strset; /*RSC_STREAM_VIDEO|RSC_STREAM_AUDIO|RSC_STREAM_META,mask 0x0f */

    unsigned int v_codec; /* see enum record_codec_format */
    unsigned int v_cbr; /** cbr: 1, vbr: 0 */
    unsigned int v_brate;
    unsigned int v_frate;
    unsigned int v_gop;
    unsigned int v_width;
    unsigned int v_height;
    unsigned int v_pic_level; /* picture level: 1-5, low to high */

    unsigned int a_codec; /* see enum record_codec_format */
    unsigned int a_sample_fmt; 
    unsigned int a_sample_rate; /* unit is HZ  */
    unsigned int a_channels; /* perhaps value: 1,2,3 */
    unsigned int a_brate;

    unsigned int m_brate;
};
typedef struct rsc_sink_attr 
{
    RSC_SINK_HANDLE (*init_sink)(int chn,struct record_sink *recsink,
	    struct rsc_stream_confset *media,struct rsc_mode_attr *mode);
    int (*fill_sink)(RSC_SINK_HANDLE handle,int stream,struct record_frame_info *frame);
    int (*exit_sink)(RSC_SINK_HANDLE handle);
}st_rsc_rec_sink;

struct rsc_vstream_attr 
{
    int on;
    unsigned char *dsrc;
    int (*preprocess)(struct record_frame_info *frame,unsigned char *source);
    int (*postprocess)(unsigned char *outpool,struct record_frame_info *frame);

    /** video media param */
    unsigned int brate;
    unsigned int codec; /* see enum record_codec_format */
    unsigned int cbr; /** cbr: 1, vbr: 0 */
    unsigned int frate;
    unsigned int gop;
    unsigned int width;
    unsigned int height;
    unsigned int pic_level; /* picture level: 1-5, low to high */
};
struct rsc_astream_attr 
{
    int on;
    unsigned char *dsrc;
    int (*preprocess)(struct record_frame_info *frame,unsigned char *source);
    int (*postprocess)(unsigned char *outpool,struct record_frame_info *frame);

    /** audio media param */
    unsigned int brate;
    unsigned int codec; /* see enum record_codec_format */
    unsigned int sample_fmt; 
    unsigned int sample_rate; /* unit is HZ  */
    unsigned int channels; /* perhaps value: 1,2,3 */
};
struct rsc_mstream_attr 
{
    int on;
    unsigned char *dsrc;
    int (*preprocess)(struct record_frame_info *frame,unsigned char *source);
    int (*postprocess)(unsigned char *outpool,struct record_frame_info *frame);

    unsigned int brate;
};
struct rsc_channel_attr
{
    int chn;
    int runflag;
    int onstart;
    int chn_temp;/* whether channel record valid is temporary or persistent */
    int unit_time_limit; // seconds
    int unit_size_limit; // MB
    struct rsc_mode_attr    modeattr;
    struct rsc_vstream_attr vstream;
    struct rsc_astream_attr astream;
    struct rsc_mstream_attr mstream;
    struct rsc_sink_attr    sink; /* static attribute */
};
struct rsc_channel_stat
{
    int chn;
    int runing;
    int recing;
    char mpoint[64];
    char abspath[128];
};

int rsc_rec_init(void);
int rsc_rec_getconf(struct rsc_channel_attr *conf);
int rsc_rec_setconf(struct rsc_channel_attr *conf,int mask);
int rsc_rec_getpenv(void);
int rsc_rec_setpenv(int flag);
int rsc_rec_isrecod(void);
int rsc_rec_start(int mask);
int rsc_rec_stop(int mask);
int rsc_rec_exit(void);

int rsc_chn_create(int chn,struct rsc_channel_attr *attr);
int rsc_chn_start(int chn);
int rsc_chn_stop(int chn);
int rsc_chn_getattr(int chn,struct rsc_channel_attr *attr);
int rsc_chn_setattr(int chn,struct rsc_channel_attr *attr);
int rsc_chn_getstat(int chn,struct rsc_channel_stat *cstat);
int rsc_chn_destroy(int chn);

#endif

